/* Universidad del Valle de Guatemala
 * CC2003 - Algoritmos y Estructuras de Datos
 * HOJA DE TRABAJO #7
 * Fecha de Entrega: Sábado 8 de Octubre de 2011
 */

/**
 * Clase que permite la implementación de un árbol binario.
 * @author José Antonio Bagur - 10275
 */

public class BinaryTree <E> {
    
        /* ATRIBUTOS DE LA CLASE BINARY TREE */
    
        protected E value;                                                      // VALOR ASOCIADO CON EL NODE
        protected BinaryTree <E> parent;                                        // PADRE DEL NODO         
        protected BinaryTree <E> left;                                          // HIJO DEL NODO
        protected BinaryTree <E> right;                                         // HIJO DEL NODO
        
        /* MÉTODOS DE LA CLASE BINARY TREE */

        /**
         * Constructor de la clase BinaryTree, genera un nodo vacío. 
         */
        public BinaryTree() {
            left = null;
            right = null;
            value = null;
            parent = null;
        }
        
        
        /**
         * Constructor de la clase BinaryTree, genera un árbol con un valor 
         * determinado y dos subárboles vacíos.
         * @param val 
         */
        public  BinaryTree(E val) {
            value = val;
            right = left = new BinaryTree<E>();
            left = null;
            right = null;
        }
        
        
        /**
         * Constructor de la clase BinaryTree, genera un árbol con un valor
         * determinado y dos subárboles.
         * @param val
         * @param left
         * @param right 
         */
        public BinaryTree(E val, BinaryTree<E> left, BinaryTree<E> right) {
            value = val;
            if (left == null) 
                left = new BinaryTree<E>();
            setLeft(left);
            if (right == null)
                right = new BinaryTree<E>();
            setRight(right);
        }
        
        
        /* MÉTODOS SET DE LA CLASE BINARY TREE */
        
        
        /**
         * Método que permite redefinir el padre de un nodo determinado.
         * @param p 
         */
        protected void setParent(BinaryTree<E> p) {
            parent = p;
        }
        
        
        /**
         * Método que permite definir el subárbol izquierdo de un nodo 
         * determinado. Redefine también el padre de dicho nodo.
         * @param l 
         */
        public void setLeft(BinaryTree<E> l) {
            if (left != null && left.getParent() == this)
                left.setParent(null);
            left = l;
            left.setParent(this);
        }
        
        
        /**
         * Método que permite definir el subárbol derecho de un nodo 
         * determinado. Rdefine también el padre de dicho nodo.
         * @param r 
         */
        public void setRight(BinaryTree<E> r) {
            if (right != null && right.getParent() == this)
                right.setParent(null);
            right = r;
            right.setParent(this);
        }
        
        
        /**
         * Método que permite definir un valor específico al nodo asociado.
         * @param val 
         */
        public void setValue(E val) {
            value = val;
        }
        
        
        /* MÉTODOS GET DE LA CLASE BINARY TREE */
        
        
        /**
         * Método que devuelve una referencia del padre asociado.
         * @return 
         */
        protected BinaryTree<E> getParent() {
            return(this.parent);
        }
        
        
        /**
         * Método que devuelve una referencia del subárbol izquierdo.
         * @return referencia al subárbol izquierdo asociado
         */
        public BinaryTree<E> getLeft() {
            return(left);
        }
        
        
        /**
         * Método que devuelve una referencia del subárbol derecho.
         * @return referencia al subárbol derecho asociado
         */
        public BinaryTree<E> getRight() {
            return(right);
        }
        
        
        /**
         * Método que devuelve el valor específico del nodo asociado. 
         * @return valor del nodo asociado
         */
        public E getValue() {
            return value;
        }
        
}   // FIN DE LA CLASE BINARYTREE
